package com.stars.easyms.datasource;

import com.stars.easyms.datasource.holder.EasyMsMasterSlaveHolder;
import com.stars.easyms.datasource.holder.EasyMsMasterSlaveDataSourceHolder;
import org.springframework.core.NamedThreadLocal;

/**
 * <p>className: EasyMsDataSourceSwitcher</p>
 * <p>description: EasyMs多主多从数据源自主切换类</p>
 *
 * @author guoguifang
 * @date 2019-10-28 14:10
 * @since 1.3.3
 */
public final class EasyMsDataSourceSwitcher {

    private static final ThreadLocal<Boolean> MANUAL_SWITCH_MULTI_DATASOURCE = new NamedThreadLocal<>("Manual switch multi dataSource");

    private static final ThreadLocal<Boolean> MANUAL_SWITCH_MASTER_SLAVE = new NamedThreadLocal<>("Manual switch master or slave dataSource");

    private static final ThreadLocal<Boolean> MANUAL_SWITCH_FIXED_DATASOURCE = new NamedThreadLocal<>("Manual switch fixed dataSource");

    public static void switchDefaultDataSource() {
        switchDataSource("");
    }

    public static void switchDataSource(String dataSourceName) {
        switchDataSource(EasyMsDataSourceFactory.getEasyMsMultiDataSource(), dataSourceName);
    }

    public static void switchAndFixedDefaultDataSource() {
        switchAndFixedDataSource("");
    }

    public static void switchAndFixedDataSource(String dataSourceName) {
        switchDataSource(dataSourceName);
        fixedDataSource();
    }

    public static void switchDefaultDataSource(EasyMsMultiDataSource easyMsMultiDataSource) {
        switchDataSource(easyMsMultiDataSource, "");
    }

    public static void switchDataSource(EasyMsMultiDataSource easyMsMultiDataSource, String dataSourceName) {
        EasyMsMasterSlaveDataSourceHolder.putMasterSlaveDataSource(easyMsMultiDataSource.getDataSource(dataSourceName));
        MANUAL_SWITCH_MULTI_DATASOURCE.set(Boolean.TRUE);
    }

    public static void switchAndFixedDefaultDataSource(EasyMsMultiDataSource easyMsMultiDataSource) {
        switchAndFixedDataSource(easyMsMultiDataSource, "");
    }

    public static void switchAndFixedDataSource(EasyMsMultiDataSource easyMsMultiDataSource, String dataSourceName) {
        switchDataSource(easyMsMultiDataSource, dataSourceName);
        fixedDataSource();
    }

    public static void switchDefaultDataSource(boolean isForceMaster) {
        switchDataSource("", isForceMaster);
    }

    public static void switchDataSource(String dataSourceName, boolean isForceMaster) {
        switchDataSource(EasyMsDataSourceFactory.getEasyMsMultiDataSource(), dataSourceName, isForceMaster);
    }

    public static void switchAndFixedDefaultDataSource(boolean isForceMaster) {
        switchAndFixedDataSource("", isForceMaster);
    }

    public static void switchAndFixedDataSource(String dataSourceName, boolean isForceMaster) {
        switchDataSource(dataSourceName, isForceMaster);
        fixedDataSource();
    }

    public static void switchDefaultDataSource(EasyMsMultiDataSource easyMsMultiDataSource, boolean isForceMaster) {
        switchDataSource(easyMsMultiDataSource, "", isForceMaster);
    }

    public static void switchDataSource(EasyMsMultiDataSource easyMsMultiDataSource, String dataSourceName, boolean isForceMaster) {
        switchDataSource(easyMsMultiDataSource, dataSourceName);
        if (isForceMaster) {
            EasyMsMasterSlaveHolder.switchMasterDataSource();
        } else {
            EasyMsMasterSlaveHolder.switchSlaveDataSource();
        }
        MANUAL_SWITCH_MASTER_SLAVE.set(Boolean.TRUE);
    }

    public static void switchAndFixedDefaultDataSource(EasyMsMultiDataSource easyMsMultiDataSource, boolean isForceMaster) {
        switchAndFixedDataSource(easyMsMultiDataSource, "", isForceMaster);
    }

    public static void switchAndFixedDataSource(EasyMsMultiDataSource easyMsMultiDataSource, String dataSourceName, boolean isForceMaster) {
        switchDataSource(easyMsMultiDataSource, dataSourceName, isForceMaster);
        fixedDataSource();
    }

    public static void clearSwitch() {
        if (MANUAL_SWITCH_FIXED_DATASOURCE.get() != null) {
            MANUAL_SWITCH_FIXED_DATASOURCE.remove();
            EasyMsMasterSlaveDataSourceHolder.clearFixedDataSource();
        }
        if (MANUAL_SWITCH_MASTER_SLAVE.get() != null) {
            MANUAL_SWITCH_MASTER_SLAVE.remove();
            EasyMsMasterSlaveHolder.clear();
        }
        if (MANUAL_SWITCH_MULTI_DATASOURCE.get() != null) {
            MANUAL_SWITCH_MULTI_DATASOURCE.remove();
            EasyMsMasterSlaveDataSourceHolder.clearMasterSlaveDataSource();
        }
    }

    private static void fixedDataSource() {
        EasyMsMasterSlaveDataSourceHolder.fixedDataSource();
        MANUAL_SWITCH_FIXED_DATASOURCE.set(Boolean.TRUE);
    }

    private EasyMsDataSourceSwitcher() {
    }
}